import 'package:dio/dio.dart';

class HttpUtil {
  static HttpUtil? _instance;
  late Dio dio;
  late BaseOptions options;
  CancelToken cancelToken = CancelToken();

  static HttpUtil getInstance() {
    _instance ??= HttpUtil._();
    return _instance!;
  }

  static Future<void> init() async {
    getInstance();
  }

  factory HttpUtil() => _instance ?? HttpUtil._();

  HttpUtil._() {
    //BaseOptions、Options、RequestOptions 都可以配置参数，优先级别依次递增，且可以根据优先级别覆盖参数
    options = BaseOptions(
      //请求基地址,可以包含子路径
      baseUrl: "",
      //连接服务器超时时间，单位是毫秒.
      connectTimeout: 10000,
      //响应流上前后两次接受到数据的间隔，单位为毫秒。
      receiveTimeout: 5000,
      //Http请求头.
      headers: {
        //do something
        "version": "1.0.0"
      },
      //请求的Content-Type，默认值是"application/json; charset=utf-8",Headers.formUrlEncodedContentType会自动编码请求体.
      contentType: Headers.formUrlEncodedContentType,
      //表示期望以那种格式(方式)接受响应数据。接受4种类型 `json`, `stream`, `plain`, `bytes`. 默认值是 `json`,
      responseType: ResponseType.json,
    );
    dio = Dio(options);
  }

  /*
   * get请求
   */
  get(url, {data, options, cancelToken}) async {
    Response response;
    try {
      response = await dio.get(url,
          queryParameters: data, options: options, cancelToken: cancelToken);
      print('[HTTP]get success---------${response.statusCode}');
      print('[HTTP]get success---------${response.data}');
      return response.data;
    } on DioError catch (e) {
      print('[HTTP]get error---------$e');
      formatError(e);
    }
  }

  /*
   * post请求
   */
  post(url, {data, options, cancelToken}) async {
    Response response;
    try {
      response = await dio.post(url,
          data: data, options: options, cancelToken: cancelToken);
      print('[HTTP]post success---------${response.data}');
      return response;
    } on DioError catch (e) {
      print('[HTTP]post error---------$e');
      formatError(e);
    }
  }

  /*
   * error统一处理
   */
  void formatError(DioError e) {
    if (e.type == DioErrorType.connectTimeout) {
      // It occurs when url is opened timeout.
      print("[HTTP]连接超时");
    } else if (e.type == DioErrorType.sendTimeout) {
      // It occurs when url is sent timeout.
      print("[HTTP]请求超时");
    } else if (e.type == DioErrorType.receiveTimeout) {
      //It occurs when receiving timeout
      print("[HTTP]响应超时");
    } else if (e.type == DioErrorType.response) {
      // When the server response, but with a incorrect status, such as 404, 503...
      print("[HTTP]出现异常");
    } else if (e.type == DioErrorType.cancel) {
      // When the request is cancelled, dio will throw a error with this type.
      print("[HTTP]请求取消");
    } else {
      //DEFAULT Default error type, Some other Error. In this case, you can read the DioError.error if it is not null.
      print("[HTTP]未知错误");
    }
  }
}
